package org.upida.validation;

import org.upida.Dtobase;

public interface IUpidaValidationContext {

	/**
	 * false, if at least on failure is recorded, otherwise true
	 */
	boolean isValid();

	/**
	 * false, if at least on failure is recorded for the current target, otherwise true
	 */
	boolean isTargetValid();

	/**
	 * false, if at least on failure is recorded for the current field, otherwise true
	 */
	boolean isFieldValid();

	/**
	 * sets current target object
	 */
	void setTarget(Dtobase value);

	/**
	 * Sets current index (used for indexed properties).
	 * For ex. current target is 'Children' and index is '7' and field 'Name' - failure would have this path - 'children[7].name'.
	 */
	void setIndex(int index);

	/**
	 * sets current field (property) name
	 */
	void setField(String name, Object value);

	/**
	 * Propagates current field to path.
	 * For ex. if current field is 'User', call AddNested(), then call SetField("Name", null) - the failure path would be - User.Name.
	 * Usually after AddNested() call, SetTarget() must be called as well.
	 */
	void addNested();

	/**
	 * goes one node back in path.
	 */
	void removeNested();

	/**
	 * registers failure without path
	 * @param msg
	 */
	void failRoot(String msg);

	/**
	 * registers failure using current path
	 * @param msg
	 */
	void fail(String msg);

	/**
	 * registers failure
	 * @param failure
	 */
	void fail(Failure failure);

	/**
	 * true if current field is assigned, otherwise false
	 */
	boolean isAssigned();

	/**
	 * true is current field is null, otherwise false
	 */
	boolean isNull();

	/**
	 * true if current field is correctly parsed, otherwise false
	 */
	boolean isValidFormat();

	/**
	 * validates if the number of assigned fields in the current target object is less or equal to max number
	 * @param msg failure message
	 */
	void mustHaveMinAssignedFieldsCount(int count, String msg);

	/**
	 * validates if the number of assigned fields in the current target object is greater or equal to min number
	 * @param msg failure message
	 */
	void mustHaveMaxAssignedFieldsCount(int count, String msg);

	/**
	 * validates if current field is assigned (was present in incoming JSON)
	 * @param msg failure message
	 */
	void mustBeAssigned(String msg);

	/**
	 * validates if current field value is not assigned by JSON deserializer
	 * @param msg failure message
	 */
	void mustBeNotAssigned(String msg);

	/**
	 * validates if current field value is correctly parsed
	 * @param msg failure message
	 */
	void mustBeValidFormat(String msg);

	/**
	 * validates if current field value is null
	 * @param msg failure message
	 */
	void mustBeNull(String msg);

	/**
	 * validates if current field value is not null
	 * @param msg failure message
	 */
	void mustBeNotNull(String msg);

	/**
	 * validates if current field value is equal to the value
	 * @param msg failure message
	 */
	void mustEqualTo(Object value, String msg);

	/**
	 * validates if current field value is not equal to the value
	 * @param msg failure message
	 */
	void mustNotEqualTo(Object value, String msg);

	/**
	 * validates if current field value is equal to one of the values
	 * @param msg failure message
	 */
	void mustEqualToOneOf(Object[] values, String msg);

	/**
	 * validates if current field value is not equal to any of the values
	 * @param msg failure message
	 */
	void mustNotEqualToAnyOf(Object[] values, String msg);

	/**
	 * validates if current field value is not empty string
	 * @param msg failure message
	 */
	void mustBeNotEmptyString(String msg);

	/**
	 * validates if current field value length (String.length) is between min and max
	 * @param msg failure message
	 */
	void mustHaveLengthBetween(int min, int max, String msg);

	/**
	 * validates if current field value (Comparable) is less or equal to m
	 * @param msg failure message
	 */
	void mustBeLessOrEqualTo(Object m, String msg);

	/**
	 * validates if current field value (Comparable) is less than m
	 * @param msg failure message
	 */
	void mustBeLessThan(Object m, String msg);

	/**
	 * validates if current field value (Comparable) is greater or equal to m
	 * @param msg failure message
	 */
	void mustBeGreaterOrEqualTo(Object m, String msg);

	/**
	 * validates if current field value (Comparable) is greater than m
	 * @param msg failure message
	 */
	void mustBeGreaterThan(Object m, String msg);

	/**
	 * validates if current field value count (Collection.size()) is between min and max count
	 * @param msg failure message
	 */
	void mustHaveCountBetween(int min, int max, String msg);

	/**
	 * validates if current field value follows the regular expression
	 * @param msg failure message
	 */
	void mustRegexpr(String expr, String msg);

	/**
	 * throws ValidationException if at least one failure was registered
	 */
	void assertValid();

	/**
	 * gets Math helper object
	 */
	IMath getMath();
}